/********************************************************
    Copyright (C), 2020-2099,SZ-STREAMING Tech. Co., Ltd.
    File name: V2xMessageDecode.c
    Author: xuzhibin 
    Date: 2020-06-12
    Description: V2X消息帧解码
********************************************************/
#include "V2xMessageDecode.h"

typedef enum {
    E_V2X_BUFFREE_CONTENTS_ONLY = 0, /* 只释放子结构buffer */
    E_V2X_BUFFREE_CONTENTS_ALL       /* 释放子父结构buffer */ 
}eV2xDecodeBufFreeType;

static asn_TYPE_descriptor_t* getDescriptorType(MessageFrame_PR msgType)
{
    asn_TYPE_descriptor_t *descriptor[6] = {&asn_DEF_MessageFrame, &asn_DEF_BSM, &asn_DEF_MAP, &asn_DEF_RSM, &asn_DEF_SPAT, &asn_DEF_RSI};

    if (msgType > MessageFrame_PR_rsiFrame) 
    {
        V2X_LOG_ERROR("msgtype error [%d]\n", msgType);
        return NULL;
    }

    return descriptor[msgType];
}

/* 消息帧解码接口, 调用者需释放MessageFrame_t内存 */
MessageFrame_t* RM_SDK_V2X_MsgFrameDecode(const void *buffer, uint32_t size)
{
    asn_dec_rval_t rval; 
    MessageFrame_t *msgFrame = NULL;

    rval = uper_decode(0, &asn_DEF_MessageFrame, (void **)&msgFrame, buffer, size, 0, 0);
    if(rval.code != RC_OK) {
        V2X_LOG_ERROR("Broken msg frame decode at byte %ld\n", (long)rval.consumed);
        return NULL;
    }
    
    /* Print the decoded MessageFrame type as XML */
    xer_fprint(stdout, &asn_DEF_MessageFrame, msgFrame);
    
    return msgFrame; 
}

/* BSM消息解码接口, 调用者需释放BSM_t内存 */
BSM_t* RM_SDK_V2X_BsmDecode(const void *buffer, uint32_t size)
{
    asn_dec_rval_t rval; 
    BSM_t *bsm = NULL;

    rval = uper_decode(0, &asn_DEF_BSM, (void **)&bsm, buffer, size, 0, 0);
    if(rval.code != RC_OK) {
        V2X_LOG_ERROR("Broken msg frame decode at byte %ld\n", (long)rval.consumed);
        return NULL;
    }

    /* Print the decoded BSM type as XML */
    xer_fprint(stdout, &asn_DEF_BSM, bsm);
    
    return bsm; 
}

/* MAP消息解码接口, 调用者需释放MAP_t内存 */
MAP_t* RM_SDK_V2X_MapDecode(const void *buffer, uint32_t size)
{
    asn_dec_rval_t rval; 
    MAP_t *map = NULL;

    rval = uper_decode(0, &asn_DEF_MAP, (void **)&map, buffer, size, 0, 0);
    if(rval.code != RC_OK) {
        V2X_LOG_ERROR("Broken msg frame decode at byte %ld\n", (long)rval.consumed);
        return NULL;
    }

    /* Print the decoded MAP type as XML */
    xer_fprint(stdout, &asn_DEF_MAP, map);
    
    return map; 
}

/* RSM消息解码接口, 调用者需释放RSM_t内存 */
RSM_t* RM_SDK_V2X_RsmDecode(const void *buffer, uint32_t size)
{
    asn_dec_rval_t rval; 
    RSM_t *rsm = NULL;

    rval = uper_decode(0, &asn_DEF_RSM, (void **)&rsm, buffer, size, 0, 0);
    if(rval.code != RC_OK) {
        V2X_LOG_ERROR("Broken msg frame decode at byte %ld\n", (long)rval.consumed);
        return NULL;
    }

    /* Print the decoded RSM type as XML */
    xer_fprint(stdout, &asn_DEF_RSM, rsm);
    
    return rsm; 
}

/* SPAT消息解码接口, 调用者需释放SPAT_t内存 */
SPAT_t* RM_SDK_V2X_SpatDecode(const void *buffer, uint32_t size)
{
    asn_dec_rval_t rval; 
    SPAT_t *spat = NULL;

    rval = uper_decode(0, &asn_DEF_SPAT, (void **)&spat, buffer, size, 0, 0);
    if(rval.code != RC_OK) {
        V2X_LOG_ERROR("Broken msg frame decode at byte %ld\n", (long)rval.consumed);
        return NULL;
    }

    /* Print the decoded SPAT type as XML */
    xer_fprint(stdout, &asn_DEF_SPAT, spat);
    
    return spat; 
}

/* RSI消息解码接口, 调用者需释放RSI_t内存 */
RSI_t* RM_SDK_V2X_RsiDecode(const void *buffer, uint32_t size)
{
    asn_dec_rval_t rval; 
    RSI_t *rsi = NULL;

    rval = uper_decode(0, &asn_DEF_RSI, (void **)&rsi, buffer, size, 0, 0);
    if(rval.code != RC_OK) {
        V2X_LOG_ERROR("Broken msg frame decode at byte %ld\n", (long)rval.consumed);
        return NULL;
    }

    /* Print the decoded RSI type as XML */
    xer_fprint(stdout, &asn_DEF_RSI, rsi);
    
    return rsi; 
}

/* 解码buffer释放接口 */
int RM_SDK_V2X_DecodeBufFree(MessageFrame_PR msgType, void* buffer)
{
    asn_TYPE_descriptor_t *descriptor = getDescriptorType(msgType);

    if (descriptor)
    {
        descriptor->free_struct(descriptor, buffer, E_V2X_BUFFREE_CONTENTS_ONLY);
        buffer = NULL;
        return E_V2X_RET_SUCC;
    }
    else 
    {
        return E_V2X_RET_FAIL;
    }   
}

